package com.zh.mp.demo.modules.order.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.zh.mp.demo.modules.goods.entity.Stock;
import com.zh.mp.demo.modules.goods.service.IStockService;
import com.zh.mp.demo.modules.member.entity.Member;
import com.zh.mp.demo.modules.member.service.IMemberService;
import com.zh.mp.demo.modules.order.entity.Log;
import com.zh.mp.demo.modules.order.entity.Orders;
import com.zh.mp.demo.modules.order.entity.OrderDto;
import com.zh.mp.demo.modules.order.mapper.OrderMapper;
import com.zh.mp.demo.modules.order.service.ILogService;
import com.zh.mp.demo.modules.order.service.IOrderService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigurationPackage;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;

/**
 * <p>
 * 订单表 服务实现类
 * </p>
 *
 * @author jobob
 * @since 2021-03-20
 */
@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Orders> implements IOrderService {

    @Autowired
    private IStockService iStockService;

    @Autowired
    private IMemberService iMemberService;

    @Autowired
    private ILogService iLogService;

    @Autowired
    private IOrderService iOrderService;

    /**
     * 创建订单
     * @param orderDto
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public Orders creatOrder(OrderDto orderDto) {
        //校验商品以及库存
        Stock stock = iStockService.getOne(new LambdaQueryWrapper<Stock>().eq(Stock::getGoodsCode,orderDto.getGoodsCode()));
        if (stock == null) {
            throw new RuntimeException("暂未查询到该库存");
        } else if (stock.getStockNum().compareTo(orderDto.getOrderNumber())<0) {
            throw new RuntimeException("商品"+stock.getGoodsName()+"库存不足");
        }
        //计算商品金额
        BigDecimal amount = stock.getGoodsPrice().multiply(BigDecimal.valueOf(orderDto.getOrderNumber()));
        //校验会员真实性
        Member member = iMemberService.getOne(new LambdaQueryWrapper<Member>().eq(Member::getMemberCode,orderDto.getMemberCode()));
        if (member == null) {
            throw new RuntimeException("未查询到该用户");
        }
        Orders order = Orders.builder()
                .orderCode(String.valueOf(System.currentTimeMillis()))
                .orderAmount(amount)
                .goodsPrice(stock.getGoodsPrice())
                .orderNumber(orderDto.getOrderNumber())
                .goodsCode(orderDto.getGoodsCode())
                .memberCode(orderDto.getMemberCode())
                .orderTime(new Date())
                .orderStatus(0).build();
        //创建订单
        this.iOrderService.saveOrder(order);
        orderDto.setOrderCode(order.getOrderCode());
        //扣减库存
        this.iStockService.updateStock(orderDto);
        //this.iOrderService.saveOrderAndUpdateStock(order,orderDto);
        //创建订单记录
        Log log = Log.builder()
                .orderCode(order.getOrderCode())
                .remake("创建订单成功")
                .createTime(new Date()).build();
        try {
            this.iLogService.saveLog(log);
        }catch (Exception e) {
            System.out.println("插入日志失败" +e.getMessage());
        }
        //提交默认支付，扣除余额 更改订单状态
        try {
            this.iOrderService.payOrder(order.getOrderCode());
        }catch (Exception e) {
            System.out.println("默认支付订单失败" +e.getMessage());
        }

        return order;
    }

    /**
     * 创建订单 and 扣减库存
     * @param order
     * @param orderDto
     */
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    @Override
    public void saveOrderAndUpdateStock (Orders order,OrderDto orderDto) {
        //创建订单
        this.baseMapper.insert(order);
        orderDto.setOrderCode(order.getOrderCode());
        Orders orders = this.iOrderService.getOne(new LambdaQueryWrapper<Orders>().eq(Orders::getOrderCode,order.getOrderCode()));
        System.out.println("创建订单下查询到订单:"+ orders);
        //扣减库存
        this.iStockService.updateStock(orderDto);
    }

    /**
     * 创建订单
     * @param order
     */
    //@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    @Override
    public void saveOrder(Orders order) {
        this.baseMapper.insert(order);
    }

    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
    @Override
    public Orders payOrder(String orderCode) {
        //先查询订单
        Orders orders = this.iOrderService.getOne(new LambdaQueryWrapper<Orders>().eq(Orders::getOrderCode,orderCode));
        System.out.println("支付时查询到订单:"+ orders);
        //更改会员余额
        this.iMemberService.update(null,new LambdaUpdateWrapper<Member>()
                .setSql("balance=balance-"+orders.getOrderAmount())
                .eq(Member::getMemberCode,orders.getMemberCode()));
        //查询会员余额
        Member member= this.iMemberService.getOne(new LambdaQueryWrapper<Member>().eq(Member::getMemberCode,orders.getMemberCode()));
        if (member.getBalance().compareTo(BigDecimal.ZERO)<0) {
            throw new RuntimeException("会员"+member.getMemberName()+"余额不足");
        }
        // 更改订单支付状态
        /*this.baseMapper.update(null,new LambdaUpdateWrapper<Orders>()
                .set(Orders::getOrderStatus,1)
                .eq(Orders::getOrderCode,orderCode));*/
        //此处status故意写错 查看 事物回滚动作
        this.baseMapper.update(null,new UpdateWrapper<Orders>()
                .set("status",1)
                .eq("order_code",orderCode));
        return orders;
    }
}
